package com.engine.salary.wrapper;

import cn.hutool.core.util.StrUtil;
import com.cloudstore.dev.api.util.Util_DataCache;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.cache.SalaryCacheKey;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.hrm.HrmStatus;
import com.engine.salary.entity.taxagent.bo.TaxAgentBO;
import com.engine.salary.entity.taxagent.dto.*;
import com.engine.salary.entity.taxagent.param.*;
import com.engine.salary.entity.taxagent.po.TaxAgentAdminPO;
import com.engine.salary.entity.taxagent.po.TaxAgentExtRangePO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.auth.AuthFilterTypeEnum;
import com.engine.salary.enums.salarysob.TargetTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.*;
import com.engine.salary.service.auth.AuthRoleService;
import com.engine.salary.service.auth.AuthRoleServiceImpl;
import com.engine.salary.service.impl.*;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import weaver.general.Util;
import weaver.hrm.User;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 个税扣缴义务人
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class TaxAgentWrapper extends Service {

    public TaxAgentBaseService getTaxAgentBaseService(User user) {
        return ServiceUtil.getService(TaxAgentBaseServiceImpl.class, user);
    }

    public TaxAgentAdminService getTaxAgentAdminService(User user) {
        return ServiceUtil.getService(TaxAgentAdminServiceImpl.class, user);
    }

    public TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    public SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    public TaxAgentManageRangeService getTaxAgentManageRangeService(User user) {
        return ServiceUtil.getService(TaxAgentManageRangeServiceImpl.class, user);
    }

    public TaxAgentExcelService getTaxAgentExcelService(User user) {
        return ServiceUtil.getService(TaxAgentExcelServiceImpl.class, user);
    }

    public AuthRoleService getAuthRoleService(User user) {
        return ServiceUtil.getService(AuthRoleServiceImpl.class, user);
    }

//    private PaymentAgencyService paymentAgencyService;
//
//    private SIEmployeeStatusMapper siEmployeeStatusMapper;
//
//    private HrmCommonHrmStatusService hrmCommonHrmStatusService;
//
//    private HrmConfigSetCache hrmConfigSetCache;

    /**
     * 是否是薪酬模块总管理员
     *
     * @param currentEmployeeId
     * @return
     */
    public Boolean isChief(Long currentEmployeeId) {
        return getTaxAgentService(user).isChief(currentEmployeeId);
    }

    /**
     * 权限信息
     *
     * @param currentEmployeeId
     * @return
     */
    public Map<String, Boolean> permission(Long currentEmployeeId) {
        Map<String, Boolean> resultMap = Maps.newHashMap();
        Boolean isChief = isChief(currentEmployeeId);
        Boolean isDefaultOpen = getTaxAgentService(user).isDefaultOpen(currentEmployeeId);
        Boolean isAdminEnable = getTaxAgentService(user).isAdminEnable(currentEmployeeId);
        Boolean isOpenDevolution = getTaxAgentService(user).isOpenDevolution();
        resultMap.put("isChief", isChief);
        resultMap.put("isDefaultOpen", isDefaultOpen);
        resultMap.put("isAdminEnable", isAdminEnable);
        resultMap.put("isOpenDevolution", isOpenDevolution);
        return resultMap;
    }

    /**
     * 个税口角义务人列表
     *
     * @param queryParam
     * @return
     */
    public PageInfo<Map<String, Object>> list(TaxAgentQueryParam queryParam) {
        // 是否开启分权
        boolean isOpenDevolution = getTaxAgentBaseService(user).isOpenDevolution();

        PageInfo<TaxAgentPO> page = getTaxAgentService(user).listPage(queryParam);
        List<TaxAgentPO> taxAgentPOS = page.getList();
        PageInfo<Map<String, Object>> listPage = new PageInfo<>();

        if (isOpenDevolution) {
            List<TaxAgentPO> list = taxAgentPOS;
            List<Long> taxAgentIds = list.stream().map(TaxAgentPO::getId).collect(Collectors.toList());
            List<TaxAgentAdminPO> taxAgentAdmins = getTaxAgentAdminService(user).listByTaxAgentIds(taxAgentIds);
            List<DataCollectionEmployee> adminList = getSalaryEmployeeService(user).getEmployeeByIdsAll(taxAgentAdmins.stream().map(TaxAgentAdminPO::getEmployeeId).distinct().collect(Collectors.toList()));
            listPage.setList(TaxAgentBO.convertToTableListDTO(taxAgentPOS, null, taxAgentAdmins, adminList));
        } else {
            listPage.setList(TaxAgentBO.convertToTableListDTO(taxAgentPOS, null));
        }

        listPage.setTotal(page.getTotal());
        listPage.setPageNum(page.getPageNum());
        listPage.setPageSize(page.getPageSize());



        //构造表格
        TaxAgentBO.buildTaxAgentTable(listPage, isOpenDevolution);

        return listPage;

    }

    public List<TaxAgentPO> listAuth(TaxAgentQueryParam taxAgentQueryParam) {
      return getTaxAgentService(user).listAuth(taxAgentQueryParam);
    }

    public List<Map<String, Object>> paymentAgencyList(TaxAgentQueryParam queryParam) {
//        List<TaxAgentPO> taxAgentPOS = getTaxAgentService(user).listByIds(queryParam.getIds());
//        List<PaymentAgencyPO> paymentAgencyPOS = paymentAgencyService.listAll(currentTenantKey);
//        SalaryAssert.notEmpty(taxAgentPOS, "taxagent data is not exist");
//        TaxAgentPO taxAgentPO = taxAgentPOS.get(0);
//        return TaxAgentBO.buildPaymentAgency(taxAgentPO.getPaymentAgency(), paymentAgencyPOS);
        return null;
    }

    public String paymentAgencySave(TaxAgentSaveParam param) {
//        List<TaxAgentPO> taxAgentPOS = getTaxAgentService(user).listByIds(Collections.singletonList(param.getId()));
//        SalaryAssert.notEmpty(taxAgentPOS, "data is not exist");
//        TaxAgentPO taxAgentPO = taxAgentPOS.get(0);
//        List<String> errorList = new ArrayList<>();
//        List<String> resultList = new ArrayList<>();
//        if (StringUtils.isNotBlank(taxAgentPO.getPaymentAgency())) {
//            List<String> originList = new ArrayList<>(Arrays.asList(taxAgentPO.getPaymentAgency().split(",")));
//            List<String> list = new ArrayList<>(Arrays.asList(param.getPaymentAgency().split(",")));
//            originList.removeAll(list);
//            if (CollectionUtils.isNotEmpty(originList)) {
//                originList.stream().forEach(e -> {
//                    List<InsuranceEmployeeStatusPO> employeeStatusPOS = new LambdaQueryChainWrapper<>(siEmployeeStatusMapper)
//                            .eq(InsuranceEmployeeStatusPO::getTenantKey)
//                            .eq(InsuranceEmployeeStatusPO::getPaymentAgency, Long.valueOf(e))
//                            .eq(InsuranceEmployeeStatusPO::getPaymentOrganization, param.getId())
//                            .list();
//                    if (CollectionUtils.isNotEmpty(employeeStatusPOS)) {
//                        errorList.add(e);
//                    }
//                });
//            }
//            if (CollectionUtils.isNotEmpty(errorList)) {
//                List<PaymentAgencyPO> paymentAgencyPOS = paymentAgencyService.listAll(currentTenantKey);
//                errorList.forEach(e -> {
//                    Optional<PaymentAgencyPO> optionalPaymentAgencyPO = paymentAgencyPOS.stream().filter(po -> Objects.equals(e, String.valueOf(po.getId()))).findFirst();
//                    optionalPaymentAgencyPO.ifPresent(paymentAgencyPO -> resultList.add(paymentAgencyPO.getAgencyName()));
//                });
//            }
//        }
//        if (CollectionUtils.isNotEmpty(resultList)) {
//            return SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmploueeId, 115128, "有员工在") + String.join(",", resultList) + SalaryI18nUtil.getI18nLabel(currentTenantKey,
//                    currentEmploueeId, 115129, "缴纳社保福利，不可取消关联");
//        } else {
//            taxAgentPO.setPaymentAgency(param.getPaymentAgency());
//            getTaxAgentService(user).paymentAgencyUpdate(taxAgentPO, currentEmploueeId);
//        }
        return "";
    }

    /**
     * 获取个税扣缴义务人表单
     *
     * @param id
     * @return
     */
    public TaxAgentFormDTO getFrom(Long id) {
        TaxAgentFormDTO taxAgentFromDTO = new TaxAgentFormDTO();
        if (id != null) {
            TaxAgentPO taxAgent = getTaxAgentService(user).getById(id);
            if (taxAgent == null) {
                throw new SalaryRunTimeException(String.format(SalaryI18nUtil.getI18nLabel(100543, "个税扣缴人不存在") + "[id:%s]", id));
            }
            BeanUtils.copyProperties(taxAgent, taxAgentFromDTO);
        }
        // 是否开启分权
        boolean isOpenDevolution = getTaxAgentBaseService(user).isOpenDevolution();
        List<TaxAgentAdminPO> admins = getTaxAgentAdminService(user).listByTaxAgentIds(Collections.singletonList(id));
        List<TaxAgentEmployeeOptionDTO> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(admins)) {
            list = admins.stream()
                    .map(admin -> {
                        Long employeeId = admin.getEmployeeId();
                        DataCollectionEmployee employee = getSalaryEmployeeService(user).getEmployeeById(employeeId);
                        String content = employee == null ? "" : employee.getUsername();
                        return TaxAgentEmployeeOptionDTO.builder().id(employeeId).content(content).build();

                    })
                    .collect(Collectors.toList());
        }

        taxAgentFromDTO.setAdminUserIds(list);

        return taxAgentFromDTO;
    }

    /**
     * 保存个税扣缴义务人
     *
     * @param saveParam
     * @return
     */
    public String save(TaxAgentSaveParam saveParam) {
        return getTaxAgentService(user).save(saveParam);
    }

    /**
     * 编辑个税扣缴义务人
     *
     * @param saveParam
     * @return
     */
    public String update(TaxAgentSaveParam saveParam) {
        return getTaxAgentService(user).update(saveParam);
    }

    /**
     * 更换管理员校验
     *
     * @param checkParam
     * @return
     */
    public Boolean adminChangeCheck(TaxAgentAdminChangeCheckParam checkParam) {
        return getTaxAgentService(user).adminChangeCheck(checkParam);
    }

    /**
     * 删除个税扣缴义务人
     *
     * @param ids
     * @return
     */
    public String delete(List<Long> ids) {
        return getTaxAgentService(user).delete(ids);
    }

    /**
     * 个税扣缴义务人下拉列表
     *
     * @return
     */
    public List<Map<String, Object>> selectList(boolean needAuth) {
        return getTaxAgentService(user).selectList(needAuth);
    }

    public List<Map<String, Object>> selectListAsAdmin() {
        return getTaxAgentService(user).selectListAsAdmin(false);
    }

    /**
     * 范围列表
     *
     * @param queryParam
     * @return
     */
    public PageInfo<TaxAgentManageRangeListDTO> listRangeInclude(TaxAgentRangeQueryParam queryParam) {
        return getTaxAgentManageRangeService(user).listPageByParamAndIncludeType(queryParam, NumberUtils.INTEGER_ONE);
    }

    /**
     * 范围排除列表
     *
     * @param queryParam
     * @return
     */
    public PageInfo<TaxAgentManageRangeListDTO> listRangeExclude(TaxAgentRangeQueryParam queryParam) {
        return getTaxAgentManageRangeService(user).listPageByParamAndIncludeType(queryParam, NumberUtils.INTEGER_ZERO);
    }

    /**
     * 获取管理范围表单
     *
     * @return
     */
    public TaxAgentManageRangeFormDTO getRangeFrom() {
        // 查询人员状态
        List<HrmStatus> hrmStatusList = UserStatusEnum.getHrmStatusList();
        //人员类型下拉列表
        List<Map<String, Object>> selectList = TargetTypeEnum.getSelectList();
        return TaxAgentManageRangeFormDTO.builder().employeeStatus(hrmStatusList).targetTypeList(selectList).build();
    }

    /**
     * 保存管理范围
     *
     * @param saveParam
     * @return
     */
    public String saveRange(TaxAgentRangeSaveParam saveParam) {
        //将select因XSS过滤造成的异常字符转换回来

        Optional.ofNullable(saveParam.getTargetParams()).orElse(new ArrayList<>())
                .forEach(targetParam -> {
                    if (StrUtil.isNotBlank(targetParam.getTarget())) {
                        targetParam.setTarget(targetParam.getTarget()
                                .replace("ｓｅｌｅｃｔ", "select")
                                .replace("ＳＥＬＥＣＴ", "SELECT")
                                .replace("ｊｏｉｎ", "join")
                                .replace("ＪＯＩＮ", "JOIN")
                                .replace("ａｎｄ", "and")
                                .replace("ＡＮＤ", "AND")
                                .replace("ｏｒ", "or")
                                .replace("ＯＲ", "OR")
                                .replace("ｉｎ", "in")
                                .replace("ＩＮ", "IN")
                                .replace("ｌｉｋｅ", "like")
                                .replace("ＬＩＫＥ", "LIKE")
                                .replace("ｅｘｉｓｔｓ", "exists")
                                .replace("ＥＸＩＳＴＳ", "EXISTS")
                                .replace("ｂｅｔｗｅｅｎ", "between")
                                .replace("ＢＥＴＷＥＥＮ", "BETWEEN")
                                .replace("ｕｎｉｏｎ", "union")
                                .replace("ＵＮＩＯＮ", "UNION")
                                .replace("ｓｕｂｓｔｒ", "substr")
                                .replace("ＳＵＢＳＴＲ", "SUBSTR")
                        );
                    }
                });


        getTaxAgentManageRangeService(user).save(saveParam);
        return StringUtils.EMPTY;
    }


    public String editRange(TaxAgentRangeSaveParam param) {
        //将select因XSS过滤造成的异常字符转换回来

        Optional.ofNullable(param.getTargetParams()).orElse(new ArrayList<>())
                .forEach(targetParam -> {
                    if (StrUtil.isNotBlank(targetParam.getTarget())) {
                        targetParam.setTarget(targetParam.getTarget()
                                .replace("ｓｅｌｅｃｔ", "select")
                                .replace("ＳＥＬＥＣＴ", "SELECT")
                                .replace("ｊｏｉｎ", "join")
                                .replace("ＪＯＩＮ", "JOIN")
                                .replace("ａｎｄ", "and")
                                .replace("ＡＮＤ", "AND")
                                .replace("ｏｒ", "or")
                                .replace("ＯＲ", "OR")
                                .replace("ｉｎ", "in")
                                .replace("ＩＮ", "IN")
                                .replace("ｌｉｋｅ", "like")
                                .replace("ＬＩＫＥ", "LIKE")
                                .replace("ｅｘｉｓｔｓ", "exists")
                                .replace("ＥＸＩＳＴＳ", "EXISTS")
                                .replace("ｂｅｔｗｅｅｎ", "between")
                                .replace("ＢＥＴＷＥＥＮ", "BETWEEN")
                                .replace("ｕｎｉｏｎ", "union")
                                .replace("ＵＮＩＯＮ", "UNION")
                                .replace("ｓｕｂｓｔｒ", "substr")
                                .replace("ＳＵＢＳＴＲ", "SUBSTR")
                        );
                    }
                });


        getTaxAgentManageRangeService(user).edit(param);
        return StringUtils.EMPTY;
    }


    /**
     * 删除管理范围
     *
     * @param ids
     * @return
     */
    public String deleteRange(Collection<Long> ids) {
        getTaxAgentManageRangeService(user).deleteByIds(ids);
        return StringUtils.EMPTY;
    }


    public PageInfo<TaxAgentExtRangePO> listExt(TaxAgentRangeExtQueryParam param) {
        return getTaxAgentManageRangeService(user).listExt(param);
    }

    /**
     * 外部人员范围
     *
     * @param saveParam
     * @return
     */
    public String saveExtRange(TaxAgentManageRangeExtSaveParam saveParam) {
        getTaxAgentManageRangeService(user).saveExtRange(saveParam);
        return StringUtils.EMPTY;
    }

    public void deleteExtRange(Collection<Long> ids) {

        getTaxAgentManageRangeService(user).deleteExtRange(ids);
    }


    /**
     * 获取个税管理的人员情况
     *
     * @param id
     * @return
     */
    public List<TaxAgentManageRangeEmployeeDTO> getEmpListInTaxAgent(Long id) {
        return getTaxAgentService(user).listTaxAgentAndEmployeeTree((long) user.getUID());
    }


    /**
     * 同步当前人员管理的个税扣缴义务人人员范围
     *
     * @return
     */
    public String syncRange() {
        long currentEmployeeId = (long) user.getUID();
        String index = SalaryCacheKey.TAX_AGENT_MANAGE_RANGE_SYNC + "-" + currentEmployeeId;
        String syncRange = Util.null2String(Util_DataCache.getObjVal(index));
        if (StringUtils.isEmpty(syncRange)) {
            TaxAgentQueryParam param = TaxAgentQueryParam.builder().build();
            param.setFilterType(AuthFilterTypeEnum.ADMIN_DATA);
            List<Long> taxAgentIds = getTaxAgentService(user).listAuth(param).stream().map(TaxAgentPO::getId).collect(Collectors.toList());
            getTaxAgentManageRangeService(user).syncManageRange(taxAgentIds, index);
        } else {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(135788, "人员范围同步过于频繁，请稍后再试"));
        }
        return SalaryI18nUtil.getI18nLabel(93945, "同步成功");
    }


    /**
     * 同步所有个税扣缴义务人的人员范围
     *
     * @return
     */
    public String syncAllRange() {
        String syncRange = Util.null2String(Util_DataCache.getObjVal(SalaryCacheKey.TAX_AGENT_MANAGE_RANGE_SYNC));
        if (StringUtils.isEmpty(syncRange)) {
            getTaxAgentManageRangeService(user).syncManageRange(null, SalaryCacheKey.TAX_AGENT_MANAGE_RANGE_SYNC);
        } else {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(135788, "人员范围同步过于频繁，请稍后再试"));
        }
        return SalaryI18nUtil.getI18nLabel(93945, "同步成功");
    }

    /**
     * 下载人员范围导入模板
     *
     * @param downloadTemplateParam
     * @return
     */
    public XSSFWorkbook exportImportTemplate(TaxAgentRangeDownloadTemplateParam downloadTemplateParam) {
        return getTaxAgentExcelService(user).downloadTemplateRange(downloadTemplateParam, user.getUID());
    }

    /**
     * 预览人员范围
     *
     * @param taxAgentImportParam
     */
    public Map<String, Object> preview(TaxAgentImportParam taxAgentImportParam) {
        return getTaxAgentExcelService(user).preview(taxAgentImportParam);
    }

    /**
     * 个税扣缴义务人-人员范围导入
     *
     * @param taxAgentImportParam
     */
    public Map<String, Object> importData(TaxAgentImportParam taxAgentImportParam) {
        return getTaxAgentManageRangeService(user).importData(taxAgentImportParam);
    }


}
